/* Copyright (c) 2010 OFXKit
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#import "OFXSignOnRequest.h"
#import "OFXDocumentRequest.h"
#import "OFXApplication.h"

@implementation OFXSignOnRequest

@synthesize accessKey;
@synthesize authenticationToken;
@synthesize clientDate;
@synthesize financialInstitution;
@synthesize generateUserKey;
@synthesize userCredential1;
@synthesize userCredential2;
@synthesize userId;
@synthesize userKey;
@synthesize userPassword;  
@synthesize ofxApplication;
@synthesize multiFactorAuthentication;

- (id)init
{
  self = [super init];
  self.multiFactorAuthentication = [[NSMutableArray alloc] init];
  self.clientDate = [NSDate dateWithTimeIntervalSinceNow:0];
  
  // set default language, appId, and appVer
  self.ofxApplication = [[OFXApplication alloc] init];
  
  return self;
}

- (NSString*)formRequestForOFXVersion:(NSUInteger)ofxVersion
{
  if (ofxVersion >= 100 && ofxVersion <= 106) {
    return [self formOFX1Request];
  } else if (ofxVersion >= 200 && ofxVersion <= 211) {
    return [self formOFX2Request];
  }
  
  // unsupported version of ofx requested
  return nil;
}

- (NSString*)formOFX1Request
{
  // in this instance the OFX 1 and 2 requests are nearly identical.
  // only difference being that OFX 1 does not support
  // GENUSERKEY.  Get the OFX2 request and just delete
  // this element.
  NSString* result = [self formOFX2Request];
  NSRange start = [result rangeOfString:@"<GENUSERKEY>"];
  NSRange end = [result rangeOfString:@"</GENUSERKEY>"];
  NSUInteger beginIdx = start.location;
  NSUInteger endIdx = end.location + end.length;
  NSString* firstHalf = [result substringToIndex:beginIdx];
  NSString* secondHalf = [result substringFromIndex:endIdx];
  return [NSString stringWithFormat:@"%@%@", firstHalf, secondHalf];
}

- (NSString*)formOFX2Request
{
  NSMutableString* result = [NSMutableString stringWithCapacity:DEFAULT_DOCUMENT_LENGTH];
  [result appendFormat:@"<DTCLIENT>%@</DTCLIENT>",
                        [defaultOFXDateFormat stringFromDate:clientDate]];

  if (userKey != nil) {
    [result appendFormat:@"<USERKEY>%@</USERKEY>", userKey];
  } else if (userId != nil && userPassword != nil) {
    [result appendFormat:@"<USERID>%@</USERID><USERPASS>%@</USERPASS>",
     userId, userPassword];
  }
  NSString* genkey = @"N";
  if (generateUserKey) genkey = @"Y";
  [result appendFormat:@"<GENUSERKEY>%@</GENUSERKEY>", genkey];
  [result appendFormat:@"<LANGUAGE>%@</LANGUAGE>", [ofxApplication language]];
    
  if (financialInstitution != nil)
  {
    [result appendFormat:@"<FI><ORG>%@</ORG><FID>%@</FID></FI>",
     [financialInstitution organization], 
     [financialInstitution financialInstitutionId]];
  }
  
  [result appendFormat:@"<APPID>%@</APPID>", [ofxApplication applicationId]];
  [result appendFormat:@"<APPVER>%@</APPVER>", 
   [ofxApplication applicationVersion]];

  if ([ofxApplication clientUID] != nil) {
    [result appendFormat:@"<CLIENTUID>%@</CLIENTUID>",
     [ofxApplication clientUID]];
  }
  
  if (userCredential1 != nil) {
    [result appendFormat:@"<USERCRED1>%@</USERCRED1>", userCredential1];
  }
  
  if (userCredential2 != nil) {
    [result appendFormat:@"<USERCRED2>%@</USERCRED2>", userCredential2];
  }

  if (authenticationToken != nil) {
    [result appendFormat:@"%@<AUTHTOKEN>%@</AUTHTOKEN>", authenticationToken];
  }
  
  if (accessKey != nil) {
    [result appendFormat:@"%@<ACCESSKEY>%@</ACCESSKEY>", accessKey];
  }
  
  // TODO: implement multifactor authentication section.
  
  return [NSString stringWithFormat:@"<SONRQ>%@</SONRQ>", result];
}

@end
